﻿#pragma once
#include "common.h"

//template<class T>
//class ObjectPool
//{
//public:
//	//至少要有申请和释放两个方法
//	T* New();
//	void Delete(T* obj);
//private:
//	char* _memory = nullptr;//指向大块内存
//	size_t _residueSize = 0;//表示大块内存还剩多少个字节的空间
//	void* _freeList = nullptr;//自由链表的头指针，用于管理回收的空间
//};
template<class T>
class ObjectPool
{
public:

	T* New()
	{
		T* obj = nullptr;
		if (_freeList)
		{
			void* next = *(void**)_freeList;
			obj = (T*)_freeList;
			_freeList = next;
		}
		else//自由链表没有空间才从大块空间中切取
		{
			if (_residueSize < sizeof(T))//当大块空间的内存不够切取一份时，从新向系统申请一个大块空间
			{
				_residueSize = 16 * 8 * 1024;//一下申请多大可以自己定义
				//char* tmp = (char*)malloc(_residueSize);
				_memory = (char*)SystemAlloc(_residueSize>>13);
				if (!_memory) throw std::bad_alloc();
			}
			size_t sz = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
			obj = (T*)_memory;
			_memory += sz;
			_residueSize -= sz;
		}
		new(obj)T;//我们的内存池分配空间支持调用对象的构造
		return obj;
	}

	void Delete(T* obj)
	{
		obj->~T();//还有析构函数
		*(void**)obj = _freeList;
		_freeList = obj;
	}
private:
	char* _memory = nullptr;
	size_t _residueSize = 0;
	void* _freeList = nullptr;
};

//
//struct TreeNode
//{
//	int _val;
//	TreeNode* _left;
//	TreeNode* _right;
//	TreeNode()
//		:_val(0)
//		, _left(nullptr)
//		, _right(nullptr)
//	{}
//};
//void TestObjectPool()
//{
//	// 申请释放的轮次
//		const size_t Rounds = 3;
//	// 每轮申请释放多少次
//
//		const size_t N = 100000;
//	size_t begin1 = clock();
//	std::vector<TreeNode*> v1;
//	v1.reserve(N);
//	for (size_t j = 0; j < Rounds; ++j)
//	{
//		for (int i = 0; i < N; ++i)
//		{
//			v1.push_back(new TreeNode);
//		}
//		for (int i = 0; i < N; ++i)
//		{
//			delete v1[i];
//		}
//		v1.clear();
//	}
//	size_t end1 = clock();
//	ObjectPool<TreeNode> TNPool;
//	size_t begin2 = clock();
//	std::vector<TreeNode*> v2;
//	v2.reserve(N);
//	for (size_t j = 0; j < Rounds; ++j)
//	{
//		for (int i = 0; i < N; ++i)
//		{
//			v2.push_back(TNPool.New());
//		}
//		for (int i = 0; i < 100000; ++i)
//		{
//			TNPool.Delete(v2[i]);
//		}
//		v2.clear();
//	}
//	size_t end2 = clock();
//	cout << "new cost time:" << end1 - begin1 << endl;
//	cout << "object pool cost time:" << end2 - begin2 << endl;
//}

//template <class T>
//class ObjectPool
//{
//public:
//	T* New()
//	{
//		T* obj = nullptr;
//		if (_freeList)//如果有回收的优先用回收的
//		{
//			obj = (T*)_freeList;
//			_freeList = *(void**)_freeList;
//		}
//		else
//		{
//			if (_residueSize < sizeof(T))//考虑剩余空间如果不足一个对象的情况
//			{
//				_residueSize = (size_t)128 * 1024;
//				_memory = (char*)malloc(_residueSize);
//				if (!_memory) throw std::bad_alloc();
//			}
//			obj = (T*)_memory;
//			//因为我们要管理回收回来的对象，所以我们要求对象的空间至少要能够储存一个地址
//			int sz = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
//			_memory += sz;
//			_residueSize -= sz;
//		}
//		new(obj)T;//定位new，会调用T类的默认构造函数
//		return obj;
//	}
//	void Delete(T* obj)
//	{
//		obj->~T();//显示的调用析构函数
//		*(void**)obj = _freeList;
//		_freeList = obj;
//	}
//private:
//	char* _memory = nullptr;//指向一个大块内存
//	size_t _residueSize = 0;//表示大块内存剩余的字节数
//	void* _freeList = nullptr;//指向链表的头，链表是用来管理回收回来的对象空间块的
//};